Modern programming languages, such as C# or the Java™ programming language, comprise built-in support for multi-threaded programming and concurrency. For example, both C# and the Java™ programming language offer the notion of threads as first-class objects of the language; in both languages, objects are associated with a mutually exclusive lock which can be used to synchronize concurrent activities. In both languages, the lock of an object is acquired for the duration of the execution of a block, using a language specific statement (such as the synchronized statement for the Java™ programming language or the lock statement for C#).
Frequently, modern programming languages such as C# or the Java™ programming language use a managed, runtime architecture: programs are compiled into an intermediate, architecture-neutral, binary form which is then executed by a virtual machine. Making the virtual machine of these managed runtime architectures capable of multi-tasking offers numerous performance advantages, such as decreased start-up time, decreased runtime overhead, and reduced memory footprint.
A multi-tasking virtual machine is capable of executing multiple programs in isolation in a single operating system process. Isolation is guaranteed by preventing program-visible interferences from happening. This is typically achieved by guaranteeing that the graph of objects created by each program is disjoint so that objects created by one task can not be reached by another task, and by precisely accounting for the resources of the OS process (e.g., threads, file descriptors) allocated to each task. Type safe programming languages prevent forging of object references, therefore a program can only access objects it has created and for which it has kept references.
It is, however, desirable to allow some objects to be shared across multiple tasks, transparently to programs, in order to further reduce the aggregate footprint of a multi-tasking virtual machine. Such transparent sharing should be limited to immutable objects in order to guarantee the absence of program-visible interferences. An immutable object is an object whose value cannot change once the object has been constructed. For example, in the multi-tasking implementation of the Java™ virtual machine, instances of java.lang.String are immutable: once constructed, an instance of java.lang.String cannot be changed. Instances of java.lang.String may be interned explicitly by programs, or implicitly by the JVM itself (JVM implementations typically intern String constants automatically, as well as String values holding the symbolic name of element of a class accessible via reflection, such as the name of methods, fields, classes and interfaces).
Transparent sharing of immutable objects across tasks is problematic when the programming language associates every object (including immutable ones) with a monitor for mutual exclusion control because interference can happen via monitor activity. To illustrate this, let us assume that a multi-tasking JVM transparently implements sharing of interned strings. Thus, the storage for any instance of java.lang.String whose method intern( ) was invoked is shared across all tasks. It is possible that two tasks can interfere with each other if both run the following code for example:
class A {static final private String COMPONENT_NAME = “A”;static private boolean IS_INITIALIZED =false;static void initialize( ) {synchronized (COMPONENT_NAME) {if (!is_initialized( )) {do_init_actions( ); // possibly a long computationIS_INITIALIZED =true;}}}. . .}
Another example that could lead to interference is the following.                synchronized (o.getClass( ).getName( )){ . . . }        
More subtle sharing can occur via canonicalization of objects. For instance, a JVM implementation may canonicalize and return an empty array of objects whenever it needs to return an empty array.
Interferences in these cases result from threads of different tasks competing for the same monitor. Thus, a thread of one task may be blocked by a thread of another task. This can easily be exploited for denial-of-service attacks. It can be argued that usage of the monitor of an immutable object is rare enough so that a strategy of “copy on first lock acquisition” could be used to avoid interferences. That is, a strategy where the immutable object would be copied so that each task operates with it's own copy of the immutable object. However, such a strategy requires updating all references in the task to the immutable object: not only references stored in objects allocated by the task, but also references stored in the local variable and expression stack of each of the task's thread. Such an operation would be extremely costly and impractical to implement.
A mechanism is therefore needed for allowing sharing of immutable objects while preventing lock-related, inter-task interference.